export type Interceptor = (...args: any[]) => Promise<boolean> | boolean

type func = () => void

export function isFunction(val: unknown): val is func {
	return typeof val === 'function'
}

export function isObject(val: unknown): val is Record<any, any> {
	return val != null && typeof val === 'object'
}

export function isPromise<T = any>(val: unknown): val is Promise<T> {
	return isObject(val) && isFunction(val.then) && isFunction(val.catch)
}

export function callInterceptor(options: {
	interceptor?: Interceptor
	args?: any[]
	done: () => void
	canceled?: () => void
}) {
	const { interceptor, args, done, canceled } = options
	if (interceptor) {
		const returnval = interceptor.apply(options, args || [])

		if (isPromise(returnval)) {
			returnval.then((value) => {
				if (value) {
					done()
				} else if (canceled) {
					canceled()
				}
			})
		} else if (returnval) {
			done()
		} else if (canceled) {
			canceled()
		}
	} else {
		done()
	}
}
